package ebhack;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class Project {
	private Document dom;
	private HashMap<String, String> files;
	private ArrayList<String> scripts;
	
	private boolean loaded;
	private String path;
	private File projFile;
	
	public Project() {
		loaded = false;
		files = new HashMap<String, String>();
		scripts = new ArrayList<String>();
	}
	
	public static String getDefaultDir() {
		return Ebhack.main.getPrefs().getValue("defaultDir");
	}
	
    public static void setDefaultDir(String dir) {
        Ebhack.main.getPrefs().setValue("defaultDir", dir);
    }
    
    public String getName() {
    	return dom.getRootElement().getChildText("Title");
    }
    
    public String getAuthor() {
    	return dom.getRootElement().getChildText("Author");
    }
    
    public String getDescription() {
    	return dom.getRootElement().getChildText("Description");
    }
    
    public String getOutputRom() {
    	return dom.getRootElement().getChildText("OutputRom");
    }
    
    public void setName(String name) {
    	dom.getRootElement().getChild("Title").setText(name);
    }
    
    public void setAuthor(String author) {
    	dom.getRootElement().getChild("Author").setText(author);
    }
    
    public void setDescription(String desc) {
    	dom.getRootElement().getChild("Description").setText(desc);
    }
    
    public void setOutputRom(String rom) {
    	dom.getRootElement().getChild("OutputRom").setText(rom);
    }
    
    public boolean isLoaded() {
    	return loaded;
    }
    
    public boolean load() {
        try
        {
            JFileChooser jfc = new JFileChooser(Project.getDefaultDir());
            jfc.setFileFilter(new FileFilter()
            {
                public boolean accept(File f)
                {
                    if ((f.getAbsolutePath().toLowerCase().endsWith(".ebproj")
                    		|| f.isDirectory())
                        && f.exists())
                    {
                        return true;
                    }
                    return false;
                }

                public String getDescription()
                {
                    return "Ebhack Project (*.ebproj)";
                }
            });

            if (jfc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION)
            {
                return load(jfc.getSelectedFile());
            }
            else
            {
                return false;
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
            return false;
        }
    }
    
    // Creates "new" fields with some default values
    private void addNewMetaData() {
    	Element e;
    	e = new Element("Title");
    	e.setText("Untitled");
    	dom.getRootElement().addContent(e);
    	e = new Element("Author");
    	e.setText(Ebhack.main.getPrefs().getValue("author", "Anonymous"));
    	dom.getRootElement().addContent(e);
    	e = new Element("Description");
    	e.setText("No description.");
    	dom.getRootElement().addContent(e);
    	e = new Element("OutputRom");
    	e.setText(projFile.getParent() + File.separator + "output.smc");
    	dom.getRootElement().addContent(e);
    }
    
    private boolean hasMetaData() {
    	return dom.getRootElement().getChild("Title") != null;
    }
    
    public boolean load(File f) {
    	setDefaultDir(f.getParent());
    	Ebhack.main.getPrefs().setValue("lastProject", f.getAbsolutePath());
    	path = f.getParent();
    	
    	if (!f.exists())
    		return false;
    	
        try {
			dom = new SAXBuilder().build(f);
		} catch (JDOMException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		loadData();
		
		projFile = f;
		
		if (!hasMetaData()) {
			addNewMetaData();
			save();
		}
		
		loaded = true;
    	
    	return true;
    }
    
    public boolean save()
    {
        try {
        	FileOutputStream fos = new FileOutputStream(projFile);
        	new XMLOutputter(Format.getPrettyFormat()).output(dom.getDocument(), fos);
            return true;
        } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        return false;
    }
    
    private void loadData() {
    	ListIterator<Element> li = dom.getRootElement().getChild("Files").getChildren("File").listIterator();
    	Element e;
    	while (li.hasNext()) {
    		e = li.next();
    		files.put(e.getAttributeValue("id"), e.getText());
    	}
    	
    	li = dom.getRootElement().getChild("CCScript").getChildren("Script").listIterator();
    	while (li.hasNext()) {
    		scripts.add(li.next().getText());
    	}
    }
    
    public String getDirectory() {
    	return path;
    }
    
    public String getFilename(String id) {
    	return path + File.separator + files.get(id);
    }
    
    public void setScripts(ArrayList<String> scripts) {
    	this.scripts = scripts;
    	
    	Element sect = dom.getRootElement().getChild("CCScript"); 
    	sect.removeChildren("Script");
    	ListIterator<String> li = scripts.listIterator();
    	while (li.hasNext()) {
    		Element e = new Element("Script");
    		e.setText(li.next());
    		sect.addContent(e);
    	}
    }
    
    public ListIterator<String> getScriptsIterator() {
    	return scripts.listIterator();
    }
    
    public void close() {
    	loaded = false;
    	files.clear();
    }
}
